package com.yida.gwj.expend.outside.handler;

import java.util.Optional;

import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.spring.annotation.MessageModel;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.apache.rocketmq.spring.core.RocketMQPushConsumerLifecycleListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.yida.common.core.exception.ServiceException;
import com.yida.gwj.common.utils.GwjEnumUtils;
import com.yida.gwj.expend.outside.domain.message.MqBaseResult;
import com.yida.gwj.expend.outside.domain.message.ResultNotifyMessage;
import com.yida.gwj.expend.outside.enums.MaintenanceFundsErrorEnum;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;

/**
 * 步骤结果回调通知
 *
 * @author liangp
 * @date 2023/02/28
 */
@Component
@RocketMQMessageListener(topic = "${gwj.expend.topic}", consumerGroup = "${gwj.expend.tag.result-notify}" + "_group", selectorExpression = "${gwj.expend.tag.result-notify}", messageModel = MessageModel.CLUSTERING)
public class ResultNotifyListenerHandler implements RocketMQListener<MessageExt>, RocketMQPushConsumerLifecycleListener {

    private final Logger log = LoggerFactory.getLogger(ResultNotifyListenerHandler.class);

    /**
     * 消息接收处理方法
     *
     * @param message 消息
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void onMessage(MessageExt message) {
        log.info("[MQ][RESULT-NOTIFY] 消息开始处理...");
        if (log.isDebugEnabled()) {
            log.debug("[MQ][RESULT-NOTIFY]参数体 -> [{}]", message.toString());
        }
        try {
            Optional<JSONObject> optionalJson = JSONUtil.toBean(StrUtil.utf8Str(message.getBody()), Optional.class);
            optionalJson.<ServiceException>orElseThrow(() -> {
                throw new ServiceException(GwjEnumUtils.getEnumConstantMsg(MaintenanceFundsErrorEnum.RESULT_NOTIFY) + "MQ基础信息获取失败");
            });
            MqBaseResult mqBaseResult = JSONUtil.toBean(optionalJson.get(), MqBaseResult.class);
            ResultNotifyMessage resultNotifyMessage = JSONUtil.toBean(mqBaseResult.getJsonMsg(), ResultNotifyMessage.class);
            if (ObjectUtil.isNull(resultNotifyMessage)) {
                throw new ServiceException(GwjEnumUtils.getEnumConstantMsg(MaintenanceFundsErrorEnum.RESULT_NOTIFY) + "业务结果通知消息转换失败");
            }
            resultNotifyMessage.checkNull();
        } catch (Exception e) {
            log.error("公维金资金申请内网业务MQ数据获取失败 -> [{}]", e);
            // TODO 失败重试或者回调通知
        }
    }

    /**
     * 消息接受前置处理
     *
     * @param defaultMqPushConsumer
     */
    @Override
    public void prepareStart(DefaultMQPushConsumer defaultMqPushConsumer) {
        // 设置重试次数
        defaultMqPushConsumer.setMaxReconsumeTimes(3);
    }
}
